bitkeeper revision 1.1338 (4266317ezHysqYzH_WRvfueqwU4i4Q)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 20 Apr 2005 10:39:58 +0000 (10:39 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 20 Apr 2005 10:39:58 +0000 (10:39 +0000)
Grant tables for FreeBSD.
Signed-off-by: Kip Macy <kmacy@fsmware.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
.rootkeys
freebsd-5.3-xen-sparse/conf/files.i386-xen
freebsd-5.3-xen-sparse/i386-xen/i386-xen/gnttab.c [new file with mode: 0644]
freebsd-5.3-xen-sparse/i386-xen/i386-xen/machdep.c
freebsd-5.3-xen-sparse/i386-xen/i386-xen/pmap.c
freebsd-5.3-xen-sparse/i386-xen/include/gnttab.h [new file with mode: 0644]
freebsd-5.3-xen-sparse/i386-xen/include/hypervisor-ifs.h
freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h
freebsd-5.3-xen-sparse/i386-xen/include/xenpmap.h
freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c

index c463985a86312d7acc2119f7f060e009bec93cde..537470ff4b1788708770f9857c519d31befd43cc 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
@@ -71,6 +71,7 @@
 423e7e88B5vxFblc-MlhxKk9e4ieBw freebsd-5.3-xen-sparse/i386-xen/i386-xen/evtchn.c
 423e7e88z_BrFu1O71-Ya4pXJpjAPQ freebsd-5.3-xen-sparse/i386-xen/i386-xen/exception.s
 423e7e88uDvAZLmABMkqOpmemyVRyw freebsd-5.3-xen-sparse/i386-xen/i386-xen/genassym.c
+4266317eeOLpvRxIjmOYQVlL4WWQsg freebsd-5.3-xen-sparse/i386-xen/i386-xen/gnttab.c
 423e7e88yr5NFQudubMnkvdb_y-Gtg freebsd-5.3-xen-sparse/i386-xen/i386-xen/hypervisor.c
 423e7e88Y-e-4RRf9nrgkVn5PXUv3Q freebsd-5.3-xen-sparse/i386-xen/i386-xen/i686_mem.c
 423e7e88b8m2cuGtOxVvs4Sok4Vk7Q freebsd-5.3-xen-sparse/i386-xen/i386-xen/initcpu.c
@@ -95,6 +96,7 @@
 423e7e8avrrUxDugrwq_GJp499DkJw freebsd-5.3-xen-sparse/i386-xen/include/ctrl_if.h
 423e7e8apY1r9Td-S0eZITNZZbfNTQ freebsd-5.3-xen-sparse/i386-xen/include/evtchn.h
 423e7e8aL9DsObEegCwtILrF6SWcAQ freebsd-5.3-xen-sparse/i386-xen/include/frame.h
+4266317eOVvN00XdcqRfDRFIrbqgvg freebsd-5.3-xen-sparse/i386-xen/include/gnttab.h
 423e7e8btv8Gojq50ggnP5A1Dkc4kA freebsd-5.3-xen-sparse/i386-xen/include/hypervisor-ifs.h
 423e7e8buhTLVFLZ33-5s8-UdADSZg freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h
 423e7e8bnHT1kMD-FPC7zHZR7l3VXw freebsd-5.3-xen-sparse/i386-xen/include/md_var.h
index 189378d4699d9f0369196987465f02d650fac23f..0c6aea90a2a99b2135006e038719a930fbd02f1d 100644 (file)
@@ -202,18 +202,19 @@ i386/i386/perfmon.c               optional        perfmon profiling-routine
 i386-xen/i386-xen/pmap.c       standard
 i386-xen/i386-xen/support.s    standard
 i386-xen/i386-xen/swtch.s      standard
-i386-xen/i386-xen/sys_machdep.c                standard
+i386-xen/i386-xen/sys_machdep.c        standard
 i386-xen/i386-xen/trap.c       standard
 i386/i386/tsc.c                        standard
-i386-xen/i386-xen/vm_machdep.c         standard
+i386-xen/i386-xen/vm_machdep.c standard
 i386-xen/i386-xen/clock.c      standard
 
 # xen specific arch-dep files
 i386-xen/i386-xen/hypervisor.c standard
 i386-xen/i386-xen/xen_machdep.c        standard
-i386-xen/i386-xen/xen_bus.c            standard
-i386-xen/i386-xen/evtchn.c             standard
-i386-xen/i386-xen/ctrl_if.c            standard
+i386-xen/i386-xen/xen_bus.c    standard
+i386-xen/i386-xen/evtchn.c     standard
+i386-xen/i386-xen/ctrl_if.c    standard
+i386-xen/i386-xen/gnttab.c     standard
 
 
 i386/isa/asc.c                 count           asc
diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/gnttab.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/gnttab.c
new file mode 100644 (file)
index 0000000..97ff0d1
--- /dev/null
@@ -0,0 +1,367 @@
+/******************************************************************************
+ * gnttab.c
+ * 
+ * Two sets of functionality:
+ * 1. Granting foreign access to our memory reservation.
+ * 2. Accessing others' memory reservations via grant references.
+ * (i.e., mechanisms for both sender and recipient of grant references)
+ * 
+ * Copyright (c) 2005, Christopher Clark
+ * Copyright (c) 2004, K A Fraser
+ */
+
+#include "opt_pmap.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+
+#include <machine/gnttab.h>
+#include <machine/pmap.h>
+
+#include <machine/hypervisor-ifs.h>
+
+#define cmpxchg(a, b, c) atomic_cmpset_int((volatile u_int *)(a),(b),(c))
+
+
+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
+static inline void rep_nop(void)
+{
+    __asm__ __volatile__ ( "rep;nop" : : : "memory" );
+}
+#define cpu_relax() rep_nop()
+
+#if 1
+#define ASSERT(_p) \
+    if ( !(_p) ) { printk("Assertion '%s': line %d, file %s\n", \
+    #_p , __LINE__, __FILE__); *(int*)0=0; }
+#else
+#define ASSERT(_p) ((void)0)
+#endif
+
+#define WPRINTK(fmt, args...) \
+    printk("xen_grant: " fmt, ##args)
+
+static grant_ref_t gnttab_free_list[NR_GRANT_ENTRIES];
+static grant_ref_t gnttab_free_head;
+
+static grant_entry_t *shared;
+#if 0
+/* /proc/xen/grant */
+static struct proc_dir_entry *grant_pde;
+#endif
+
+/*
+ * Lock-free grant-entry allocator
+ */
+
+static inline int
+get_free_entry(void)
+{
+    grant_ref_t fh, nfh = gnttab_free_head;
+    do { if ( unlikely((fh = nfh) == NR_GRANT_ENTRIES) ) return -1; }
+    while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh,
+                                    gnttab_free_list[fh])) != fh) );
+    return fh;
+}
+
+static inline void
+put_free_entry(grant_ref_t ref)
+{
+    grant_ref_t fh, nfh = gnttab_free_head;
+    do { gnttab_free_list[ref] = fh = nfh; wmb(); }
+    while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh, ref)) != fh) );
+}
+
+/*
+ * Public grant-issuing interface functions
+ */
+
+int
+gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
+{
+    int ref;
+    
+    if ( unlikely((ref = get_free_entry()) == -1) )
+        return -ENOSPC;
+
+    shared[ref].frame = frame;
+    shared[ref].domid = domid;
+    wmb();
+    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
+
+    return ref;
+}
+
+void
+gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, 
+                               unsigned long frame, int readonly)
+{
+    shared[ref].frame = frame;
+    shared[ref].domid = domid;
+    wmb();
+    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
+}
+
+
+int
+gnttab_query_foreign_access(grant_ref_t ref)
+{
+    uint16_t nflags;
+
+    nflags = shared[ref].flags;
+
+    return (nflags & (GTF_reading|GTF_writing));
+}
+
+void
+gnttab_end_foreign_access(grant_ref_t ref, int readonly)
+{
+    uint16_t flags, nflags;
+
+    nflags = shared[ref].flags;
+    do {
+        if ( (flags = nflags) & (GTF_reading|GTF_writing) )
+            printk("WARNING: g.e. still in use!\n");
+    }
+    while ( (nflags = cmpxchg(&shared[ref].flags, flags, 0)) != flags );
+
+    put_free_entry(ref);
+}
+
+int
+gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
+{
+    int ref;
+
+    if ( unlikely((ref = get_free_entry()) == -1) )
+        return -ENOSPC;
+
+    shared[ref].frame = pfn;
+    shared[ref].domid = domid;
+    wmb();
+    shared[ref].flags = GTF_accept_transfer;
+
+    return ref;
+}
+
+void
+gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid, 
+                                 unsigned long pfn)
+{
+    shared[ref].frame = pfn;
+    shared[ref].domid = domid;
+    wmb();
+    shared[ref].flags = GTF_accept_transfer;
+}
+
+unsigned long
+gnttab_end_foreign_transfer(grant_ref_t ref)
+{
+    unsigned long frame = 0;
+    uint16_t           flags;
+
+    flags = shared[ref].flags;
+    ASSERT(flags == (GTF_accept_transfer | GTF_transfer_committed));
+
+    /*
+     * If a transfer is committed then wait for the frame address to appear.
+     * Otherwise invalidate the grant entry against future use.
+     */
+    if ( likely(flags != GTF_accept_transfer) ||
+         (cmpxchg(&shared[ref].flags, flags, 0) != GTF_accept_transfer) )
+        while ( unlikely((frame = shared[ref].frame) == 0) )
+            cpu_relax();
+
+    put_free_entry(ref);
+
+    return frame;
+}
+
+void
+gnttab_free_grant_references(uint16_t count, grant_ref_t head)
+{
+    /* TODO: O(N)...? */
+    grant_ref_t to_die = 0, next = head;
+    int i;
+
+    for ( i = 0; i < count; i++ )
+        to_die = next;
+        next = gnttab_free_list[next];
+        put_free_entry( to_die );
+}
+
+int
+gnttab_alloc_grant_references(uint16_t count, grant_ref_t *head, 
+                             grant_ref_t *terminal)
+{
+    int i;
+    grant_ref_t h = gnttab_free_head;
+
+    for ( i = 0; i < count; i++ )
+        if ( unlikely(get_free_entry() == -1) )
+            goto not_enough_refs;
+
+    *head = h;
+    *terminal = gnttab_free_head;
+
+    return 0;
+
+not_enough_refs:
+    gnttab_free_head = h;
+    return -ENOSPC;
+}
+
+int
+gnttab_claim_grant_reference(grant_ref_t *private_head, grant_ref_t  terminal )
+{
+    grant_ref_t g;
+    if ( unlikely((g = *private_head) == terminal) )
+        return -ENOSPC;
+    *private_head = gnttab_free_list[g];
+    return g;
+}
+
+void
+gnttab_release_grant_reference( grant_ref_t *private_head,
+                                grant_ref_t  release )
+{
+    gnttab_free_list[release] = *private_head;
+    *private_head = release;
+}
+#ifdef notyet
+static int 
+grant_ioctl(struct cdev *dev, u_long cmd, caddr_t data, 
+           int flag, struct thread *td)
+{
+
+    int                     ret;
+    privcmd_hypercall_t     hypercall;
+
+    /* XXX Need safety checks here if using for anything other
+     *     than debugging */
+    return -ENOSYS;
+
+    if ( cmd != IOCTL_PRIVCMD_HYPERCALL )
+        return -ENOSYS;
+
+    if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
+        return -EFAULT;
+
+    if ( hypercall.op != __HYPERVISOR_grant_table_op )
+        return -ENOSYS;
+
+    /* hypercall-invoking asm taken from privcmd.c */
+    __asm__ __volatile__ (
+        "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
+        "movl  4(%%eax),%%ebx ;"
+        "movl  8(%%eax),%%ecx ;"
+        "movl 12(%%eax),%%edx ;"
+        "movl 16(%%eax),%%esi ;"
+        "movl 20(%%eax),%%edi ;"
+        "movl   (%%eax),%%eax ;"
+        TRAP_INSTR "; "
+        "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
+        : "=a" (ret) : "0" (&hypercall) : "memory" );
+
+    return ret;
+
+}
+
+static struct cdevsw gnttab_cdevsw = {
+    d_ioctl:  grant_ioctl,
+};
+
+static int 
+grant_read(char *page, char **start, off_t off,
+          int count, int *eof, void *data)
+{
+    int             len;
+    unsigned int    i;
+    grant_entry_t  *gt;
+
+    gt = (grant_entry_t *)shared;
+    len = 0;
+
+    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
+        /* TODO: safety catch here until this can handle >PAGE_SIZE output */
+        if (len > (PAGE_SIZE - 200))
+        {
+            len += sprintf( page + len, "Truncated.\n");
+            break;
+        }
+
+        if ( gt[i].flags )
+            len += sprintf( page + len,
+                    "Grant: ref (0x%x) flags (0x%hx) dom (0x%hx) frame (0x%x)\n", 
+                    i,
+                    gt[i].flags,
+                    gt[i].domid,
+                    gt[i].frame );
+
+    *eof = 1;
+    return len;
+}
+
+static int 
+grant_write(struct file *file, const char __user *buffer,
+           unsigned long count, void *data)
+{
+    /* TODO: implement this */
+    return -ENOSYS;
+}
+#endif
+static int 
+gnttab_init(void *unused)
+{
+    gnttab_setup_table_t setup;
+    unsigned long        frames[NR_GRANT_FRAMES];
+    int                  i;
+
+    setup.dom        = DOMID_SELF;
+    setup.nr_frames  = NR_GRANT_FRAMES;
+    setup.frame_list = frames;
+
+    if (HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0)
+        panic("grant table setup failed\n");
+    if (setup.status != 0)
+        panic("non-zero status in grant table setup\n");
+    shared = (grant_entry_t *)kmem_alloc_nofault(kernel_map, NR_GRANT_FRAMES);
+
+    for (i = 0; i < NR_GRANT_FRAMES; i++) 
+       pmap_kenter_ma((vm_offset_t)(shared + (i*PAGE_SIZE)), frames[i] << PAGE_SHIFT);
+
+    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
+        gnttab_free_list[i] = i + 1;
+#if 0
+    /*
+     *  /proc/xen/grant : used by libxc to access grant tables
+     */
+    if ( (grant_pde = create_xen_proc_entry("grant", 0600)) == NULL )
+    {
+        WPRINTK("Unable to create grant xen proc entry\n");
+        return -1;
+    }
+
+    grant_file_ops.read   = grant_pde->proc_fops->read;
+    grant_file_ops.write  = grant_pde->proc_fops->write;
+
+    grant_pde->proc_fops  = &grant_file_ops;
+
+    grant_pde->read_proc  = &grant_read;
+    grant_pde->write_proc = &grant_write;
+#endif
+    printk("Grant table initialized\n");
+    return 0;
+}
+
+SYSINIT(gnttab, SI_SUB_PSEUDO, SI_ORDER_FIRST, gnttab_init, NULL);
index 0d18e7d4c058646391b6869fbfc6a6af6974fffd..f954962f1ea425b17228a0f9f520934248673fc4 100644 (file)
@@ -1387,6 +1387,7 @@ initvalues(start_info_t *startinfo)
 { 
     int i;
 #ifdef WRITABLE_PAGETABLES
+    XENPRINTF("using writable pagetables\n");
     HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
 #endif
 
@@ -1457,7 +1458,7 @@ initvalues(start_info_t *startinfo)
 
     /* allocate remainder of NKPT pages */
     for (i = 0; i < NKPT-1; i++, tmpindex++)
-       PT_SET_VA(((unsigned long *)startinfo->pt_base) + KPTDI + i + 1, (tmpindex << PAGE_SHIFT)| PG_M | PG_RW | PG_V | PG_A, TRUE);
+       PD_SET_VA(((unsigned long *)startinfo->pt_base) + KPTDI + i + 1, (tmpindex << PAGE_SHIFT)| PG_M | PG_RW | PG_V | PG_A, TRUE);
     tmpindex += NKPT-1;
     PT_UPDATES_FLUSH();
 
index 89705be1af37b7b43d6bc46fa029a31ed34fe9d8..a9e536f41ce340537a1c6564ca51402125efcc8c 100644 (file)
@@ -381,9 +381,10 @@ pmap_bootstrap(firstaddr, loadaddr)
         * CMAP1/CMAP2 are used for zeroing and copying pages.
         * CMAP3 is used for the idle process page zeroing.
         */
-       SYSMAP(caddr_t, CMAP1, CADDR1, 1)
-       SYSMAP(caddr_t, CMAP2, CADDR2, 1)
-       SYSMAP(caddr_t, CMAP3, CADDR3, 1)
+       SYSMAP(caddr_t, CMAP1, CADDR1, 1);
+       SYSMAP(caddr_t, CMAP2, CADDR2, 1);
+       SYSMAP(caddr_t, CMAP3, CADDR3, 1);
+
        PT_CLEAR_VA(CMAP3, TRUE);
 
        mtx_init(&CMAPCADDR12_lock, "CMAPCADDR12", NULL, MTX_DEF);
@@ -416,7 +417,7 @@ pmap_bootstrap(firstaddr, loadaddr)
        PT_CLEAR_VA(CMAP2, FALSE);
 
        for (i = 0; i < NKPT; i++)
-               PT_CLEAR_VA(&PTD[i], FALSE);
+               PD_CLEAR_VA(&PTD[i], FALSE);
        PT_UPDATES_FLUSH();
 #ifdef XEN_UNNEEDED
        /* Turn on PG_G on kernel page(s) */
@@ -961,6 +962,19 @@ pmap_kenter(vm_offset_t va, vm_paddr_t pa)
        pte_store(pte, pa | PG_RW | PG_V | pgeflag);
 }
 
+/*
+ * Add a wired page to the kva.
+ * Note: not SMP coherent.
+ */
+PMAP_INLINE void 
+pmap_kenter_ma(vm_offset_t va, vm_paddr_t ma)
+{
+       pt_entry_t *pte;
+
+       pte = vtopte(va);
+       PT_SET_VA_MA(pte, ma | PG_RW | PG_V | pgeflag, TRUE);
+}
+
 /*
  * Remove a page from the kernel pagetables.
  * Note: not SMP coherent.
diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/gnttab.h b/freebsd-5.3-xen-sparse/i386-xen/include/gnttab.h
new file mode 100644 (file)
index 0000000..76733a0
--- /dev/null
@@ -0,0 +1,71 @@
+/******************************************************************************
+ * gnttab.h
+ * 
+ * Two sets of functionality:
+ * 1. Granting foreign access to our memory reservation.
+ * 2. Accessing others' memory reservations via grant references.
+ * (i.e., mechanisms for both sender and recipient of grant references)
+ * 
+ * Copyright (c) 2004, K A Fraser
+ * Copyright (c) 2005, Christopher Clark
+ */
+
+#ifndef __ASM_GNTTAB_H__
+#define __ASM_GNTTAB_H__
+
+#include <machine/hypervisor.h>
+#include <machine/hypervisor-ifs.h>
+
+/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
+#define NR_GRANT_FRAMES 4
+#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
+
+int
+gnttab_grant_foreign_access(
+    domid_t domid, unsigned long frame, int readonly);
+
+void
+gnttab_end_foreign_access(
+    grant_ref_t ref, int readonly);
+
+int
+gnttab_grant_foreign_transfer(
+    domid_t domid, unsigned long pfn);
+
+unsigned long
+gnttab_end_foreign_transfer(
+    grant_ref_t ref);
+
+int
+gnttab_query_foreign_access( 
+    grant_ref_t ref );
+
+/*
+ * operations on reserved batches of grant references
+ */
+int
+gnttab_alloc_grant_references(
+    uint16_t count, grant_ref_t *pprivate_head, grant_ref_t *private_terminal );
+
+void
+gnttab_free_grant_references(
+    uint16_t count, grant_ref_t private_head );
+
+int
+gnttab_claim_grant_reference( grant_ref_t *pprivate_head, grant_ref_t terminal
+);
+
+void
+gnttab_release_grant_reference(
+    grant_ref_t *private_head, grant_ref_t release );
+
+void
+gnttab_grant_foreign_access_ref(
+    grant_ref_t ref, domid_t domid, unsigned long frame, int readonly);
+
+void
+gnttab_grant_foreign_transfer_ref(
+    grant_ref_t, domid_t domid, unsigned long pfn);
+
+
+#endif /* __ASM_GNTTAB_H__ */
index 4f75d27a9a31ef80433c4897907538d546a04306..a77ee4a6be5bb2e450b02b407c68cd16fb667c48 100644 (file)
@@ -11,6 +11,7 @@
 #define u32 uint32_t
 #define u64 uint64_t
 
+#define CONFIG_XEN_BLKDEV_GRANT
 #include <machine/xen-public/xen.h>
 #include <machine/xen-public/io/domain_controller.h>
 #include <machine/xen-public/io/netif.h>
@@ -19,6 +20,7 @@
 #include <machine/xen-public/event_channel.h>
 #include <machine/xen-public/sched_ctl.h>
 #include <machine/xen-public/physdev.h>
+#include <machine/xen-public/grant_table.h>
 #undef  blkif_sector_t                 /* XXX pre-processor didn't do the */
 #define blkif_sector_t uint64_t                /* right thing */
 
index cfae32112915429c530bd9957a1af34f76f92582..c93727d90428517521653c35210898cb8a039ad7 100644 (file)
@@ -38,7 +38,8 @@ typedef struct { unsigned long pte_low, pte_high; } pte_t;
  * Assembler stubs for hyper-calls.
  */
 
-static inline int HYPERVISOR_set_trap_table(trap_info_t *table)
+static inline int 
+HYPERVISOR_set_trap_table(trap_info_t *table)
 {
     int ret;
     __asm__ __volatile__ (
@@ -83,7 +84,8 @@ HYPERVISOR_mmuext_op(
 
 
 
-static inline int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
+static inline int 
+HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
 {
     int ret;
     __asm__ __volatile__ (
@@ -95,7 +97,8 @@ static inline int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
     return ret;
 }
 
-static inline int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
+static inline int 
+HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
 {
     int ret;
     __asm__ __volatile__ (
@@ -106,7 +109,8 @@ static inline int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
     return ret;
 }
 
-static inline int HYPERVISOR_set_callbacks(
+static inline int 
+HYPERVISOR_set_callbacks(
     unsigned long event_selector, unsigned long event_address,
     unsigned long failsafe_selector, unsigned long failsafe_address)
 {
@@ -120,7 +124,8 @@ static inline int HYPERVISOR_set_callbacks(
     return ret;
 }
 
-static inline int HYPERVISOR_fpu_taskswitch(void)
+static inline int 
+HYPERVISOR_fpu_taskswitch(void)
 {
     int ret;
     __asm__ __volatile__ (
@@ -130,7 +135,8 @@ static inline int HYPERVISOR_fpu_taskswitch(void)
     return ret;
 }
 
-static inline int HYPERVISOR_yield(void)
+static inline int 
+HYPERVISOR_yield(void)
 {
     int ret;
     __asm__ __volatile__ (
@@ -141,7 +147,8 @@ static inline int HYPERVISOR_yield(void)
     return ret;
 }
 
-static inline int HYPERVISOR_block(void)
+static inline int 
+HYPERVISOR_block(void)
 {
     int ret;
     __asm__ __volatile__ (
@@ -152,7 +159,8 @@ static inline int HYPERVISOR_block(void)
     return ret;
 }
 
-static inline int HYPERVISOR_shutdown(void)
+static inline int 
+HYPERVISOR_shutdown(void)
 {
     int ret;
     __asm__ __volatile__ (
@@ -164,7 +172,8 @@ static inline int HYPERVISOR_shutdown(void)
     return ret;
 }
 
-static inline int HYPERVISOR_reboot(void)
+static inline int 
+HYPERVISOR_reboot(void)
 {
     int ret;
     __asm__ __volatile__ (
@@ -176,7 +185,8 @@ static inline int HYPERVISOR_reboot(void)
     return ret;
 }
 
-static inline int HYPERVISOR_suspend(unsigned long srec)
+static inline int 
+HYPERVISOR_suspend(unsigned long srec)
 {
     int ret;
     /* NB. On suspend, control software expects a suspend record in %esi. */
@@ -189,7 +199,8 @@ static inline int HYPERVISOR_suspend(unsigned long srec)
     return ret;
 }
 
-static inline long HYPERVISOR_set_timer_op(uint64_t timeout)
+static inline long 
+HYPERVISOR_set_timer_op(uint64_t timeout)
 {
     int ret;
     unsigned long timeout_hi = (unsigned long)(timeout>>32);
@@ -202,7 +213,8 @@ static inline long HYPERVISOR_set_timer_op(uint64_t timeout)
     return ret;
 }
 
-static inline int HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
+static inline int 
+HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
 {
     int ret;
     dom0_op->interface_version = DOM0_INTERFACE_VERSION;
@@ -214,7 +226,8 @@ static inline int HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
     return ret;
 }
 
-static inline int HYPERVISOR_set_debugreg(int reg, unsigned long value)
+static inline int 
+HYPERVISOR_set_debugreg(int reg, unsigned long value)
 {
     int ret;
     __asm__ __volatile__ (
@@ -225,7 +238,8 @@ static inline int HYPERVISOR_set_debugreg(int reg, unsigned long value)
     return ret;
 }
 
-static inline unsigned long HYPERVISOR_get_debugreg(int reg)
+static inline unsigned long 
+HYPERVISOR_get_debugreg(int reg)
 {
     unsigned long ret;
     __asm__ __volatile__ (
@@ -236,7 +250,8 @@ static inline unsigned long HYPERVISOR_get_debugreg(int reg)
     return ret;
 }
 
-static inline int HYPERVISOR_update_descriptor(
+static inline int 
+HYPERVISOR_update_descriptor(
     unsigned long pa, unsigned long word1, unsigned long word2)
 {
     int ret;
@@ -248,7 +263,8 @@ static inline int HYPERVISOR_update_descriptor(
     return ret;
 }
 
-static inline int HYPERVISOR_set_fast_trap(int idx)
+static inline int 
+HYPERVISOR_set_fast_trap(int idx)
 {
     int ret;
     __asm__ __volatile__ (
@@ -259,9 +275,10 @@ static inline int HYPERVISOR_set_fast_trap(int idx)
     return ret;
 }
 
-static inline int HYPERVISOR_dom_mem_op(unsigned int   op,
-                                       unsigned long *pages,
-                                       unsigned long  nr_pages)
+static inline int 
+HYPERVISOR_dom_mem_op(unsigned int   op,
+                     unsigned long *pages,
+                     unsigned long  nr_pages)
 {
     int ret;
     __asm__ __volatile__ (
@@ -271,7 +288,8 @@ static inline int HYPERVISOR_dom_mem_op(unsigned int   op,
     return ret;
 }
 
-static inline int HYPERVISOR_multicall(void *call_list, int nr_calls)
+static inline int 
+HYPERVISOR_multicall(void *call_list, int nr_calls)
 {
     int ret;
     __asm__ __volatile__ (
@@ -282,7 +300,8 @@ static inline int HYPERVISOR_multicall(void *call_list, int nr_calls)
     return ret;
 }
 
-static inline int HYPERVISOR_update_va_mapping(
+static inline int 
+HYPERVISOR_update_va_mapping(
     unsigned long page_nr, unsigned long new_val, unsigned long flags)
 {
     int ret;
@@ -300,7 +319,8 @@ static inline int HYPERVISOR_update_va_mapping(
     return ret;
 }
 
-static inline int HYPERVISOR_event_channel_op(void *op)
+static inline int 
+HYPERVISOR_event_channel_op(void *op)
 {
     int ret;
     __asm__ __volatile__ (
@@ -311,7 +331,8 @@ static inline int HYPERVISOR_event_channel_op(void *op)
     return ret;
 }
 
-static inline int HYPERVISOR_xen_version(int cmd)
+static inline int 
+HYPERVISOR_xen_version(int cmd)
 {
     int ret;
     __asm__ __volatile__ (
@@ -322,7 +343,8 @@ static inline int HYPERVISOR_xen_version(int cmd)
     return ret;
 }
 
-static inline int HYPERVISOR_console_io(int cmd, int count, char *str)
+static inline int 
+HYPERVISOR_console_io(int cmd, int count, char *str)
 {
     int ret;
     __asm__ __volatile__ (
@@ -333,36 +355,62 @@ static inline int HYPERVISOR_console_io(int cmd, int count, char *str)
     return ret;
 }
 
-static __inline int HYPERVISOR_console_write(char *str, int count)
+static inline int 
+HYPERVISOR_console_write(char *str, int count)
 {
     return HYPERVISOR_console_io(CONSOLEIO_write, count, str); 
 }
 
-static inline int HYPERVISOR_physdev_op(void *physdev_op)
+static inline int 
+HYPERVISOR_physdev_op(void *physdev_op)
 {
     int ret;
+    unsigned long ign;
+
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret) : "0" (__HYPERVISOR_physdev_op),
-        "b" (physdev_op) : "memory" );
+        : "=a" (ret), "=b" (ign) 
+        : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op) 
+       : "memory" );
 
     return ret;
 }
 
-static inline int HYPERVISOR_update_va_mapping_otherdomain(
-    unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid)
+static inline int
+HYPERVISOR_grant_table_op(
+    unsigned int cmd, void *uop, unsigned int count)
 {
     int ret;
+    unsigned long ign1, ign2, ign3;
+
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping_otherdomain), 
-        "b" (page_nr), "c" ((new_val).pte_low), "d" (flags), "S" (domid) :
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
+        : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count)
+        : "memory" );
+
+    return ret;
+}
+
+static inline int 
+HYPERVISOR_update_va_mapping_otherdomain(
+    unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
+{
+    int ret;
+    unsigned long ign1, ign2, ign3, ign4;
+       
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
+        : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
+          "1" (va), "2" ((new_val).pte_low), "3" (flags), "4" (domid) :
         "memory" );
-    
+
     return ret;
 } 
 
-static inline int HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
+static inline int 
+HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
 {
     int ret;
     __asm__ __volatile__ (
index 2149d5dc483024af60bc33b06d53654e44c4284b..c0fa939241ce46e61f4d41006beb50645948b574 100644 (file)
@@ -60,6 +60,14 @@ void pmap_ref(pt_entry_t *pte, unsigned long ma);
 #endif
 
 #define ALWAYS_SYNC 0
+#define PT_DEBUG
+
+#ifdef PT_DEBUG
+#define PT_LOG() printk("WP PT_SET %s:%d\n", __FILE__, __LINE__) 
+#else
+#define PT_LOG()
+#endif
+
 #define pmap_valid_entry(E)           ((E) & PG_V) /* is PDE or PTE valid? */
 
 #define        PT_GET(_ptp)                                            \
@@ -68,15 +76,18 @@ void pmap_ref(pt_entry_t *pte, unsigned long ma);
 #ifdef WRITABLE_PAGETABLES
 #define PT_SET_VA(_ptp,_npte,sync) do {                                \
         PMAP_REF((_ptp), xpmap_ptom(_npte));                    \
-        *(_ptp) = xpmap_ptom((_npte));                            \
+        PT_LOG();                                               \
+        *(_ptp) = xpmap_ptom((_npte));                          \
 } while (/*CONSTCOND*/0)
-#define PT_SET_VA_MA(_ptp,_npte,sync) do {                 \
+#define PT_SET_VA_MA(_ptp,_npte,sync) do {                     \
         PMAP_REF((_ptp), (_npte));                              \
-        *(_ptp) = (_npte);                                          \
+        PT_LOG();                                               \
+        *(_ptp) = (_npte);                                      \
 } while (/*CONSTCOND*/0)
 #define PT_CLEAR_VA(_ptp, sync) do {                           \
         PMAP_REF((pt_entry_t *)(_ptp), 0);                      \
-        *(_ptp) = 0;                                              \
+        PT_LOG();                                               \
+        *(_ptp) = 0;                                            \
 } while (/*CONSTCOND*/0)
 
 #define PD_SET_VA(_ptp,_npte,sync) do {                                \
@@ -85,7 +96,7 @@ void pmap_ref(pt_entry_t *pte, unsigned long ma);
                            xpmap_ptom((_npte)));               \
        if (sync || ALWAYS_SYNC) xen_flush_queue();             \
 } while (/*CONSTCOND*/0)
-#define PD_SET_VA_MA(_ptp,_npte,sync) do {                 \
+#define PD_SET_VA_MA(_ptp,_npte,sync) do {                     \
         PMAP_REF((_ptp), (_npte));                              \
        xen_queue_pt_update((pt_entry_t *)vtomach((_ptp)), (_npte)); \
        if (sync || ALWAYS_SYNC) xen_flush_queue();             \
@@ -105,9 +116,9 @@ void pmap_ref(pt_entry_t *pte, unsigned long ma);
                            xpmap_ptom(_npte));                 \
        if (sync || ALWAYS_SYNC) xen_flush_queue();             \
 } while (/*CONSTCOND*/0)
-#define PT_SET_VA_MA(_ptp,_npte,sync) do {                 \
+#define PT_SET_VA_MA(_ptp,_npte,sync) do {                     \
         PMAP_REF((_ptp), (_npte));                              \
-       xen_queue_pt_update((pt_entry_t *)vtomach(_ptp), _npte); \
+       xen_queue_pt_update((pt_entry_t *)vtomach(_ptp), _npte);\
        if (sync || ALWAYS_SYNC) xen_flush_queue();             \
 } while (/*CONSTCOND*/0)
 #define PT_CLEAR_VA(_ptp, sync) do {                           \
index a9e9b2cad1a5b2dbcddbac5b0a84320a160eb5f6..5aeb212153ffef809a1f5d2d925b2ac5f40ff64e 100644 (file)
 #include <machine/ctrl_if.h>
 #include <machine/xenfunc.h>
 
+
+
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+#include <machine/gnttab.h>
+#endif
+
 /* prototypes */
 struct xb_softc;
 static void xb_startio(struct xb_softc *sc);
 static void xb_vbdinit(void);
 static void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp);
 static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id);
+static void blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp, unsigned long address);
 
 struct xb_softc {
     device_t             xb_dev;
@@ -104,6 +111,14 @@ static blkif_front_ring_t   blk_ring;
 
 #define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
 
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+static domid_t rdomid = 0;
+static grant_ref_t gref_head, gref_terminal;
+#define MAXIMUM_OUTSTANDING_BLOCK_REQS \
+    (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
+#endif
+
+
 static unsigned long rec_ring_free;            
 blkif_request_t rec_ring[BLK_RING_SIZE];
 
@@ -151,8 +166,9 @@ ADD_ID_TO_FREELIST( unsigned long id )
     rec_ring_free = id;
 }
 
-static inline void translate_req_to_pfn(blkif_request_t *xreq,
-                                        blkif_request_t *req)
+static inline void 
+translate_req_to_pfn(blkif_request_t *xreq,
+                    blkif_request_t *req)
 {
     int i;
 
@@ -163,7 +179,11 @@ static inline void translate_req_to_pfn(blkif_request_t *xreq,
     xreq->sector_number = req->sector_number;
 
     for ( i = 0; i < req->nr_segments; i++ ){
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+        xreq->frame_and_sects[i] = req->frame_and_sects[i];
+#else
         xreq->frame_and_sects[i] = xpmap_mtop(req->frame_and_sects[i]);
+#endif
     }
 }
 
@@ -179,7 +199,11 @@ static inline void translate_req_to_mfn(blkif_request_t *xreq,
     xreq->sector_number = req->sector_number;
 
     for ( i = 0; i < req->nr_segments; i++ ){
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+        xreq->frame_and_sects[i] = req->frame_and_sects[i];
+#else
         xreq->frame_and_sects[i] = xpmap_ptom(req->frame_and_sects[i]);
+#endif
     }
 }
 
@@ -340,6 +364,9 @@ xb_startio(struct xb_softc *sc)
     int                        s, queued = 0;
     unsigned long id;
     unsigned int fsect, lsect;
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+    int ref;
+#endif
 
     
     if (unlikely(blkif_state != BLKIF_STATE_CONNECTED))
@@ -396,12 +423,26 @@ xb_startio(struct xb_softc *sc)
        req->nr_segments  = 1;  /* not doing scatter/gather since buffer
                                 * chaining is not supported.
                                 */
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+            /* install a grant reference. */
+            ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
+            KASSERT( ref != -ENOSPC, ("grant_reference failed") );
+
+            gnttab_grant_foreign_access_ref(
+                        ref,
+                        rdomid,
+                        buffer_ma >> PAGE_SHIFT,
+                        req->operation & 1 ); /* ??? */
+
+            req->frame_and_sects[0] =
+                (((uint32_t) ref) << 16) | (fsect << 3) | lsect;
+#else
        /*
         * upper bits represent the machine address of the buffer and the
         * lower bits is the number of sectors to be read/written.
         */
        req->frame_and_sects[0] = buffer_ma | (fsect << 3) | lsect; 
-
+#endif
        /* Keep a private copy so we can reissue requests when recovering. */
        translate_req_to_pfn( &rec_ring[id], req);
 
@@ -503,9 +544,14 @@ xb_vbdinit(void)
     memset(&req, 0, sizeof(req)); 
     req.operation = BLKIF_OP_PROBE;
     req.nr_segments = 1;
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+    blkif_control_probe_send(&req, &rsp,
+                             (unsigned long)(vtomach(buf)));
+    
+#else
     req.frame_and_sects[0] = vtomach(buf) | 7;
     blkif_control_send(&req, &rsp);
-    
+#endif
     if ( rsp.status <= 0 ) {
         printk("xb_identify: Could not identify disks (%d)\n", rsp.status);
        free(buf, M_DEVBUF);
@@ -526,6 +572,22 @@ xb_vbdinit(void)
 
 /*****************************  COMMON CODE  *******************************/
 
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+static void 
+blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp,
+                              unsigned long address)
+{
+    int ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
+    KASSERT( ref != -ENOSPC, ("couldn't get grant reference") );
+
+    gnttab_grant_foreign_access_ref( ref, rdomid, address >> PAGE_SHIFT, 0 );
+
+    req->frame_and_sects[0] = (((uint32_t) ref) << 16) | 7;
+
+    blkif_control_send(req, rsp);
+}
+#endif
+
 void 
 blkif_control_send(blkif_request_t *req, blkif_response_t *rsp)
 {
@@ -713,6 +775,10 @@ blkif_connect(blkif_fe_interface_status_t *status)
 
     blkif_evtchn = status->evtchn;
     blkif_irq    = bind_evtchn_to_irq(blkif_evtchn);
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+    rdomid       = status->domid;
+#endif
+
 
     err = intr_add_handler("xbd", blkif_irq, 
                           (driver_intr_t *)xb_response_intr, NULL,
@@ -875,6 +941,14 @@ xb_init(void *unused)
 
     printk("[XEN] Initialising virtual block device driver\n");
 
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+    if ( 0 > gnttab_alloc_grant_references( MAXIMUM_OUTSTANDING_BLOCK_REQS,
+                                            &gref_head, &gref_terminal ))
+        return;
+    printk("Blkif frontend is using grant tables.\n");
+#endif
+
+
     rec_ring_free = 0;
     for (i = 0; i < BLK_RING_SIZE; i++) {
        rec_ring[i].id = i+1;
@@ -899,13 +973,21 @@ blkdev_resume(void)
 }
 #endif
 
-/* XXXXX THIS IS A TEMPORARY FUNCTION UNTIL WE GET GRANT TABLES */
-
 void 
 blkif_completion(blkif_request_t *req)
 {
     int i;
 
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+    grant_ref_t gref;
+
+    for ( i = 0; i < req->nr_segments; i++ )
+    {
+        gref = blkif_gref_from_fas(req->frame_and_sects[i]);
+        gnttab_release_grant_reference(&gref_head, gref);
+    }
+#else
+    /* This is a hack to get the dirty logging bits set */
     switch ( req->operation )
     {
     case BLKIF_OP_READ:
@@ -917,7 +999,7 @@ blkif_completion(blkif_request_t *req)
        }
        break;
     }
-    
+#endif    
 }
 MTX_SYSINIT(ioreq, &blkif_io_lock, "BIO LOCK", MTX_SPIN | MTX_NOWITNESS); /* XXX how does one enroll a lock? */
 SYSINIT(xbdev, SI_SUB_PSEUDO, SI_ORDER_ANY, xb_init, NULL)